# -*- coding: utf-8 -*-
"""
@Time： 2023/12/20 16:20
@Auth： gubei
@File：views.py
@IDE：PyCharm
@Description：系统路由相关接口
"""
import os
import platform
import socket
import sys
import time
import uuid
from datetime import datetime
from pathlib import Path
from typing import List, Optional
import json

import psutil
from fastapi import APIRouter, Depends, Request, File, UploadFile, Form, WebSocket, WebSocketDisconnect, Query, Header, HTTPException
from fastapi.responses import FileResponse

from core.auth.oauth2 import get_current_user
from utils.response import R
from api.routes.events import manager, get_token_user

router = APIRouter()


@router.get("/health", summary="健康检查", description="检查API服务是否正常运行")
async def health_check():
    """
    健康检查接口，可用于Kubernetes、Docker等容器环境的健康检查
    
    Returns:
        dict: 包含状态和时间戳的JSON响应
    """
    return {
        "status": "ok",
        "timestamp": datetime.now().isoformat()
    }


@router.get("/system/info", summary="获取系统信息", description="获取服务器系统信息")
async def system_info(current_user = Depends(get_current_user)):
    """
    获取系统信息接口，包含服务器操作系统、CPU、内存等信息
    
    Returns:
        dict: 包含系统信息的JSON响应
    """
    try:
        # 系统基本信息
        system_info = {
            "os": {
                "name": platform.system(),
                "version": platform.version(),
                "platform": platform.platform(),
            },
            "python": {
                "version": sys.version,
                "implementation": platform.python_implementation(),
            },
            "network": {
                "hostname": socket.gethostname(),
                "ip": socket.gethostbyname(socket.gethostname()),
            },
            "hardware": {
                "cpu_count": psutil.cpu_count(),
                "cpu_percent": psutil.cpu_percent(),
                "memory": {
                    "total": psutil.virtual_memory().total / (1024 * 1024 * 1024),  # GB
                    "available": psutil.virtual_memory().available / (1024 * 1024 * 1024),  # GB
                    "percent": psutil.virtual_memory().percent,
                },
                "disk": {
                    "total": psutil.disk_usage('/').total / (1024 * 1024 * 1024),  # GB
                    "used": psutil.disk_usage('/').used / (1024 * 1024 * 1024),  # GB
                    "free": psutil.disk_usage('/').free / (1024 * 1024 * 1024),  # GB
                    "percent": psutil.disk_usage('/').percent,
                }
            },
            "process": {
                "pid": os.getpid(),
                "memory_info": {
                    "rss": psutil.Process(os.getpid()).memory_info().rss / (1024 * 1024),  # MB
                    "vms": psutil.Process(os.getpid()).memory_info().vms / (1024 * 1024),  # MB
                },
                "cpu_percent": psutil.Process(os.getpid()).cpu_percent(),
                "create_time": datetime.fromtimestamp(psutil.Process(os.getpid()).create_time()).isoformat(),
                "status": psutil.Process(os.getpid()).status(),
            },
            "time": {
                "now": datetime.now().isoformat(),
                "uptime": time.time() - psutil.boot_time(),
            }
        }
        return R.suc(data=system_info)
    except Exception as e:
        return R.err(msg=f"获取系统信息失败: {str(e)}")


@router.get("/system/routes", summary="获取所有路由", description="获取API所有路由信息")
async def get_all_routes(request: Request, current_user = Depends(get_current_user)):
    """
    获取所有API路由信息
    
    Returns:
        dict: 包含路由信息的JSON响应
    """
    routes = []
    
    for route in request.app.routes:
        route_info = {
            "path": route.path,
            "name": route.name,
            "methods": getattr(route, "methods", None),
        }
        routes.append(route_info)
    
    return R.suc(data=routes)


# 创建上传目录
UPLOAD_DIR = Path("./uploads")
UPLOAD_DIR.mkdir(exist_ok=True)

@router.post("/upload", summary="上传文件", description="上传单个或多个文件")
async def upload_file(
    files: List[UploadFile] = File(...),
    folder: str = Form("default"),
    current_user = Depends(get_current_user)
):
    """
    文件上传接口，支持单个或多个文件上传
    
    - **files**: 要上传的文件（可多选）
    - **folder**: 存储文件夹（可选，默认为'default'）
    
    Returns:
        dict: 包含上传文件信息的JSON响应
    """
    # 创建指定文件夹
    folder_path = UPLOAD_DIR / folder
    folder_path.mkdir(exist_ok=True)
    
    result = []
    for file in files:
        # 生成唯一文件名
        file_ext = os.path.splitext(file.filename)[1]
        unique_filename = f"{uuid.uuid4()}{file_ext}"
        file_path = folder_path / unique_filename
        
        # 保存文件
        with open(file_path, "wb") as f:
            f.write(await file.read())
        
        # 添加文件信息到结果
        result.append({
            "filename": file.filename,
            "content_type": file.content_type,
            "size": os.path.getsize(file_path),
            "stored_filename": unique_filename,
            "path": f"/api/file/{folder}/{unique_filename}",
        })
    
    return R.suc(data=result, msg=f"成功上传 {len(files)} 个文件")


@router.get("/file/{folder}/{filename}", summary="获取文件", description="下载指定文件")
async def get_file(folder: str, filename: str):
    """
    文件下载接口，通过文件夹和文件名获取文件
    
    - **folder**: 文件夹名称
    - **filename**: 文件名
    
    Returns:
        FileResponse: 文件响应
    """
    file_path = UPLOAD_DIR / folder / filename
    
    if not file_path.exists():
        return R.not_found(msg="文件不存在")
    
    return FileResponse(
        path=file_path,
        filename=filename,
        media_type="application/octet-stream"
    )


@router.websocket("/ws")
async def websocket_endpoint(websocket: WebSocket):
    """
    WebSocket广播端点，连接后可接收广播消息
    """
    await manager.connect(websocket)
    try:
        while True:
            # 等待消息，但这个端点只用于接收广播，不处理接收到的消息
            data = await websocket.receive_text()
    except WebSocketDisconnect:
        manager.disconnect(websocket)


@router.websocket("/ws/{client_id}")
async def websocket_endpoint_user(
    websocket: WebSocket, 
    client_id: str, 
    token: Optional[str] = Query(None)
):
    """
    WebSocket用户专属端点，需要认证
    
    - **client_id**: 客户端ID（必须与token中的用户名匹配）
    - **token**: JWT认证令牌（可选，如提供则验证身份）
    """
    # 如果提供了令牌，验证用户身份
    if token:
        try:
            username = await get_token_user(token)
            # 验证client_id是否与令牌中的用户名匹配
            if username != client_id:
                await websocket.close(code=1008, reason="认证失败：用户ID不匹配")
                return
        except HTTPException:
            await websocket.close(code=1008, reason="认证失败：无效的令牌")
            return
    
    # 接受连接
    await manager.connect(websocket, client_id)
    try:
        # 发送欢迎消息
        await websocket.send_text(f"欢迎 {client_id}!")
        
        # 持续接收消息
        while True:
            data = await websocket.receive_text()
            # 将消息发回客户端确认
            await websocket.send_text(f"您说: {data}")
    except WebSocketDisconnect:
        manager.disconnect(websocket, client_id)


@router.post("/broadcast", summary="广播消息", description="向所有连接的客户端广播消息")
async def broadcast_message(
    message: str = Form(...),
    message_type: str = Form("notification"),
    current_user = Depends(get_current_user)
):
    """
    广播消息接口，向所有连接的WebSocket客户端发送消息
    
    - **message**: 消息内容
    - **message_type**: 消息类型（默认为notification）
    
    Returns:
        dict: 包含广播结果的JSON响应
    """
    # 创建广播消息
    data = {
        "type": message_type,
        "message": message,
        "sender": current_user.userName,
        "timestamp": datetime.now().isoformat()
    }
    
    # 广播消息
    await manager.broadcast(json.dumps(data))
    
    return R.suc(msg=f"消息已广播", data={"recipients_count": len(manager.broadcast_connections) + sum(len(connections) for connections in manager.active_connections.values())})


@router.post("/message/{client_id}", summary="发送私信", description="向特定用户发送消息")
async def send_personal_message(
    client_id: str,
    message: str = Form(...),
    message_type: str = Form("personal"),
    current_user = Depends(get_current_user)
):
    """
    发送私信接口，向特定用户发送WebSocket消息
    
    - **client_id**: 接收消息的用户ID
    - **message**: 消息内容
    - **message_type**: 消息类型（默认为personal）
    
    Returns:
        dict: 包含发送结果的JSON响应
    """
    # 检查用户是否在线
    if client_id not in manager.active_connections:
        return R.err(msg=f"用户 {client_id} 不在线")
    
    # 创建私信消息
    data = {
        "type": message_type,
        "message": message,
        "sender": current_user.userName,
        "timestamp": datetime.now().isoformat()
    }
    
    # 发送私信
    await manager.send_personal_message(json.dumps(data), client_id)
    
    return R.suc(msg=f"消息已发送给 {client_id}", data={"recipients_count": len(manager.active_connections[client_id])})


@router.get("/get-async-routes", summary='获取routes')
async def get_async_routes():
    data = {
        "success": True,
        "data": [
            {
                "path": "/system",
                "meta": {
                    "icon": "ri:settings-3-line",
                    "title": "menus.hssysManagement",
                    "rank": 10
                },
                "children": [
                    {
                        "path": "/system/user/index",
                        "name": "SystemUser",
                        "meta": {
                            "icon": "ri:admin-line",
                            "title": "menus.hsUser",
                            "roles": [
                                "admin"
                            ]
                        }
                    },
                    {
                        "path": "/system/role/index",
                        "name": "SystemRole",
                        "meta": {
                            "icon": "ri:admin-fill",
                            "title": "menus.hsRole",
                            "roles": [
                                "admin"
                            ]
                        }
                    },
                    {
                        "path": "/system/menu/index",
                        "name": "SystemMenu",
                        "meta": {
                            "icon": "ep:menu",
                            "title": "menus.hsSystemMenu",
                            "roles": [
                                "admin"
                            ]
                        }
                    },
                    {
                        "path": "/system/dept/index",
                        "name": "SystemDept",
                        "meta": {
                            "icon": "ri:git-branch-line",
                            "title": "menus.hsDept",
                            "roles": [
                                "admin"
                            ]
                        }
                    }
                ]
            },
            {
                "path": "/permission",
                "meta": {
                    "title": "menus.permission",
                    "icon": "ep:lollipop",
                    "rank": 9
                },
                "children": [
                    {
                        "path": "/permission/page/index",
                        "name": "PermissionPage",
                        "meta": {
                            "title": "menus.permissionPage",
                            "roles": [
                                "admin",
                                "common"
                            ]
                        }
                    },
                    {
                        "path": "/permission/button/index",
                        "name": "PermissionButton",
                        "meta": {
                            "title": "menus.permissionButton",
                            "roles": [
                                "admin",
                                "common"
                            ],
                            "auths": [
                                "permission:btn:add",
                                "permission:btn:edit",
                                "permission:btn:delete"
                            ]
                        }
                    }
                ]
            },
            # {
            #     "path": "/iframe",
            #     "meta": {
            #         "icon": "ep:monitor",
            #         "title": "menus.hsExternalPage",
            #         "rank": 7
            #     },
            #     "children": [
            #         {
            #             "path": "/iframe/external",
            #             "meta": {
            #                 "title": "menus.hsExternalDoc"
            #             },
            #             "children": [
            #                 {
            #                     "path": "/external",
            #                     "name": "https://yiming_chang.gitee.io/pure-admin-doc",
            #                     "meta": {
            #                         "title": "menus.externalLink",
            #                         "roles": [
            #                             "admin",
            #                             "common"
            #                         ]
            #                     }
            #                 },
            #                 {
            #                     "path": "/pureutilsLink",
            #                     "name": "https://pure-admin-utils.netlify.app/",
            #                     "meta": {
            #                         "title": "menus.pureutilsLink",
            #                         "roles": [
            #                             "admin",
            #                             "common"
            #                         ]
            #                     }
            #                 }
            #             ]
            #         },
            #         {
            #             "path": "/iframe/embedded",
            #             "meta": {
            #                 "title": "menus.hsEmbeddedDoc"
            #             },
            #             "children": [
            #                 {
            #                     "path": "/iframe/ep",
            #                     "name": "FrameEp",
            #                     "meta": {
            #                         "title": "menus.hsEpDocument",
            #                         "frameSrc": "https://element-plus.org/zh-CN/",
            #                         "keepAlive": True,
            #                         "roles": [
            #                             "admin",
            #                             "common"
            #                         ]
            #                     }
            #                 },
            #                 {
            #                     "path": "/iframe/tailwindcss",
            #                     "name": "FrameTailwindcss",
            #                     "meta": {
            #                         "title": "menus.hsTailwindcssDocument",
            #                         "frameSrc": "https://tailwindcss.com/docs/installation",
            #                         "keepAlive": True,
            #                         "roles": [
            #                             "admin",
            #                             "common"
            #                         ]
            #                     }
            #                 },
            #                 {
            #                     "path": "/iframe/vue3",
            #                     "name": "FrameVue",
            #                     "meta": {
            #                         "title": "menus.hsVueDocument",
            #                         "frameSrc": "https://cn.vuejs.org/",
            #                         "keepAlive": True,
            #                         "roles": [
            #                             "admin",
            #                             "common"
            #                         ]
            #                     }
            #                 },
            #                 {
            #                     "path": "/iframe/vite",
            #                     "name": "FrameVite",
            #                     "meta": {
            #                         "title": "menus.hsViteDocument",
            #                         "frameSrc": "https://cn.vitejs.dev/",
            #                         "keepAlive": True,
            #                         "roles": [
            #                             "admin",
            #                             "common"
            #                         ]
            #                     }
            #                 },
            #                 {
            #                     "path": "/iframe/pinia",
            #                     "name": "FramePinia",
            #                     "meta": {
            #                         "title": "menus.hsPiniaDocument",
            #                         "frameSrc": "https://pinia.vuejs.org/zh/index.html",
            #                         "keepAlive": True,
            #                         "roles": [
            #                             "admin",
            #                             "common"
            #                         ]
            #                     }
            #                 },
            #                 {
            #                     "path": "/iframe/vue-router",
            #                     "name": "FrameRouter",
            #                     "meta": {
            #                         "title": "menus.hsRouterDocument",
            #                         "frameSrc": "https://router.vuejs.org/zh/",
            #                         "keepAlive": True,
            #                         "roles": [
            #                             "admin",
            #                             "common"
            #                         ]
            #                     }
            #                 }
            #             ]
            #         }
            #     ]
            # },
            # {
            #     "path": "/tabs",
            #     "meta": {
            #         "icon": "ri:bookmark-2-line",
            #         "title": "menus.hstabs",
            #         "rank": 11
            #     },
            #     "children": [
            #         {
            #             "path": "/tabs/index",
            #             "name": "Tabs",
            #             "meta": {
            #                 "title": "menus.hstabs",
            #                 "roles": [
            #                     "admin",
            #                     "common"
            #                 ]
            #             }
            #         },
            #         {
            #             "path": "/tabs/query-detail",
            #             "name": "TabQueryDetail",
            #             "meta": {
            #                 "showLink": False,
            #                 "activePath": "/tabs/index",
            #                 "roles": [
            #                     "admin",
            #                     "common"
            #                 ]
            #             }
            #         },
            #         {
            #             "path": "/tabs/params-detail/:id",
            #             "component": "params-detail",
            #             "name": "TabParamsDetail",
            #             "meta": {
            #                 "showLink": False,
            #                 "activePath": "/tabs/index",
            #                 "roles": [
            #                     "admin",
            #                     "common"
            #                 ]
            #             }
            #         }
            #     ]
            # }
        ]
    }

    return data



